package com.yegs.jltqc.serviceImpl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.yegs.jltqc.TO.RpInComePageQuery;
import com.yegs.jltqc.TO.RpproducePageQuery;
import com.yegs.jltqc.U8Service.CgbarcodeService;
import com.yegs.jltqc.U8Service.PpbarcodeService;
import com.yegs.jltqc.U8Service.U8InComePService;
import com.yegs.jltqc.U8Service.U8QcProduceService;
import com.yegs.jltqc.U8ServiceImpl.U8RpInComeServiceImpl;
import com.yegs.jltqc.VO.RpInCome;
import com.yegs.jltqc.VO.RpInComeBarcode;
import com.yegs.jltqc.VO.RpProduce;
import com.yegs.jltqc.VO.RpProduceBarcode;
import com.yegs.jltqc.common.StoreException;
import com.yegs.jltqc.config.ConcurentCache;
import com.yegs.jltqc.dao.RpInComeBarcodeRepository;
import com.yegs.jltqc.dao.RpInComeRepository;
import com.yegs.jltqc.dao.RpProduceBarcodeRepository;
import com.yegs.jltqc.dao.RpProduceRepository;
import com.yegs.jltqc.service.RpInComeService;
import com.yegs.jltqc.service.RpProduceService;
import com.yegs.jltqc.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
public class RpInComeServiceImpl implements RpInComeService {


    private final String MEASUREMENT_weijian = "未检";
    private final String MEASUREMENT_yijian = "已检";
    private final String MEASUREMENT_hege = "合格";
    private final String MEASUREMENT_tecai = "特采";
    private final String MEASUREMENT_quanjian = "全检";
    private final String MEASUREMENT_fangong = "返工";

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private RpInComeRepository rpInComeRepository;

    @Autowired
    private U8InComePService u8InComePService;


    @Autowired
    private PpbarcodeService ppbarcodeService;
    @Autowired
    private CgbarcodeService cgbarcodeService;

    @Autowired
    private RpInComeBarcodeRepository rpInComeBarcodeRepository;

    @Override
    public RpInCome save(RpInCome rpInCome) throws Exception {
        try {
            //新单
            if(rpInCome.getId() == null){
                rpInCome.setCreateBy(ConcurentCache.getUserName());
                rpInCome.setCreateTime(new Date());
            }else {
                RpInCome one = rpInComeRepository.getOne(rpInCome.getId());
                rpInCome.setUpdateBy(ConcurentCache.getUserName());
                rpInCome.setUpdateTime(new Date());
                rpInCome.getBarcodes().forEach(item->{
                    logger.info(item.getCbarcode());
                    ppbarcodeService.updateYmhPoqcdata(rpInCome.getMeasurement(),item.getCbarcode());
                    if(one.getMeasurement() == null && ( MEASUREMENT_hege.equals(rpInCome.getMeasurement()) || MEASUREMENT_tecai.equals(rpInCome.getMeasurement()))){
                        String finish = u8InComePService.finish(item.getCbarcode(), ConcurentCache.getUserName());
                        ObjectMapper objectMapper = new ObjectMapper();
                        HashMap<String,Object> hashMap = null;
                        try {
                            hashMap = objectMapper.readValue(finish, HashMap.class);
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                            throw new StoreException(e.getMessage());
                        }
                        if("0".equals(hashMap.get("StatusCode").toString())){
                            rpInCome.setBillno((String) hashMap.get("Data"));
                        }else{
                            //throw new StoreException(hashMap.get("Info").toString());
                        }
                    }
                });

            }
            return rpInComeRepository.save(rpInCome);
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }
    }
    @Override
    public RpInCome get(Long id) {
        return rpInComeRepository.getOne(id);
    }


    @Override
    public void del(Long id) {
        rpInComeRepository.deleteById(id);
    }

    @Override
    public Page<RpInCome> query(RpInComePageQuery query) {

        PageRequest request = PageRequest.of(query.getPageIndex() - 1, query.getPageSize(), Sort.Direction.DESC,"id");
        Specification<RpInCome> specification = new Specification<RpInCome>() {
            @Override
            public Predicate toPredicate(Root<RpInCome> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if(query.getCsocode() != null && query.getCsocode().trim().length() > 0){
                    predicates.add(criteriaBuilder.like(root.get("csocode"),"%" + query.getCsocode() + "%"));
                }
                if(query.getSddate() != null){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ddate"),query.getSddate()));
                }
                if(query.getEddate() != null){
                    predicates.add(criteriaBuilder.lessThan(root.get("ddate"), DateUtils.addDay(query.getEddate())));
                }
                if(query.getDdate() != null){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ddate"),query.getDdate()));
                    predicates.add(criteriaBuilder.lessThan(root.get("ddate"), DateUtils.addDay(query.getDdate())));
                }
                if(MEASUREMENT_weijian.equals(query.getMeasurement())){
                    predicates.add(criteriaBuilder.isNull(root.get("measurement")));
                }
                if(MEASUREMENT_yijian.equals(query.getMeasurement())){
                    predicates.add(criteriaBuilder.isNotNull(root.get("measurement")));
                }
                if(MEASUREMENT_hege.equals(query.getMeasurement())||MEASUREMENT_fangong.equals(query.getMeasurement())
                        ||MEASUREMENT_quanjian.equals(query.getMeasurement())||MEASUREMENT_tecai.equals(query.getMeasurement())){
                    predicates.add(criteriaBuilder.equal(root.get("measurement"),query.getMeasurement()));
                }

                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
       return rpInComeRepository.findAll(specification, request);
    }

    @Override
    public Long getNext(Long id) {
        if(id == null){
            RpInCome rpInCome = rpInComeRepository.findFirstByOrderByIdDesc();
            if(rpInCome != null) {
                return rpInCome.getId();
            }
        }
        RpInCome rpInCome = rpInComeRepository.findFirstByIdIsAfter(id);
        if(rpInCome == null){ rpInCome = rpInComeRepository.findFirstByOrderByIdDesc(); }
        if(rpInCome != null){
            return rpInCome.getId();
        }
        return null;
    }

    @Override
    public Long getLast(Long id) {
        if(id == null){
            RpInCome rpInCome = rpInComeRepository.findFirstByOrderByIdDesc();
            if(rpInCome != null) {
                return rpInCome.getId();
            }
        }
        else{
            RpInCome rpInCome = rpInComeRepository.findFirstByIdBeforeOrderByIdDesc(id);
            if(rpInCome == null){ rpInCome = rpInComeRepository.findFirstByOrderById(); }
            if(rpInCome != null){
                return rpInCome.getId();
            }
        }
        return null;
    }

    @Override
    public RpInCome findRpProduceByBarcode(String barcode) {
        Map<String, Object> map = cgbarcodeService.findByBarcode(barcode);
        if(map == null){
            return null;
        }
        Integer autoid = (Integer) map.get("autoid");
        return rpInComeRepository.findFirstByAutoidOrderByIdDesc(autoid + 0l);
    }
    @Override
    public RpInCome findRpIncomeBySubBarcode(String barcode) {
        RpInComeBarcode rpb = rpInComeBarcodeRepository.findFirstByCbarcodeOrderByIdDesc(barcode);
        if(rpb == null){
            return null;
        }
        return rpInComeRepository.getOne(rpb.getRefId());
    }
}
